/*
 * LocalTurnSubStateController.cpp
 *
 *  Created on: Dec 29, 2011
 *      Author: rudi
 */
#include <vector>
#include <wx/filename.h>
#include "LocalTurnSubStateController.h"
#include "RemoteTurnSubStateController.h"
#include "GameStartedGameStateController.h"
#include "MainPanel.h"
#include "MainFrame.h"
#include "Vehicle.h"
#include "App.h"
#include "WxUtils.h"
#include "Configuration.h"

LocalTurnSubStateController::LocalTurnSubStateController(): mLevel(NULL), mOriginalLevel(NULL), mDynamicDrawController(NULL),
															mMouseMotionCounter(0)
{
	wxChar pathSeparator = wxFileName::GetPathSeparator();
	wxString level = wxGetApp().getActualLevel();
	wxString imagePath = wxGetCwd() + pathSeparator + wxGetApp().getConfiguration()->getLevels()->getPath() + pathSeparator + level + pathSeparator + level + wxT(".bmp");
	int dotSize = wxGetApp().getConfiguration()->getDotSize();
	wxPoint localPosition = wxGetApp().getConfiguration()->getLevels()->getLevel(level)->getVehicleA()->getPosition();
	wxPoint remotePosition = wxGetApp().getConfiguration()->getLevels()->getLevel(level)->getVehicleB()->getPosition();
	SmartPointer<Vehicle> localVehicle = NULL;
	SmartPointer<Vehicle> remoteVehicle = NULL;
	SmartPointer<std::vector<wxPoint> > localVehicleArrows = NULL;
	SmartPointer<std::vector<wxPoint> > remoteVehicleArrows = NULL;

	// Start the game itself
	mLevel = new wxBitmap(imagePath, wxBITMAP_TYPE_BMP);
	mOriginalLevel = new wxImage(mLevel->ConvertToImage());
	// Create the vehicles and put them on the starting point
	localVehicle = new Vehicle(localPosition, mLevel, dotSize);
	remoteVehicle = new Vehicle(remotePosition, mLevel, dotSize);
	// At the beginning the lists of points are empty
	localVehicleArrows = new std::vector<wxPoint>();
	remoteVehicleArrows = new std::vector<wxPoint>();
	mDynamicDrawController = new DynamicDrawController(mLevel, mOriginalLevel, localVehicle, remoteVehicle, localVehicleArrows, remoteVehicleArrows, WxUtils::INVALID_POINT);
	wxGetApp().getMainFrame()->GetStatusBar()->SetStatusText(wxT("Your turn"));
	// Load the new level
	wxGetApp().getMainFrame()->getMainPanel()->Refresh();
}

LocalTurnSubStateController::LocalTurnSubStateController(SmartPointer<wxBitmap> level,
													     SmartPointer<wxImage> originalLevel,
													     SmartPointer<DynamicDrawController> dynamicDrawController): mLevel(level),
																													 mOriginalLevel(originalLevel),
																													 mDynamicDrawController(dynamicDrawController),
																													 mMouseMotionCounter(0)
{
	wxGetApp().getMainFrame()->GetStatusBar()->SetStatusText(wxT("Your turn"));
}

/*virtual*/
LocalTurnSubStateController::~LocalTurnSubStateController()
{
	// Nothing to do yet
}

//
// Methods inherited from Controller
//

void LocalTurnSubStateController::handleMouseDown(const wxPoint& position)
{
	mMouseMotionCounter = 0;
	// Send the information to the other side
	this->sendDataToRemoteSide(NetworkEventData::MOUSE_DOWN, position);
	// Let the draw controller handle the event
	mDynamicDrawController->handleMouseDown(position);
}

void LocalTurnSubStateController::handleMouseUp(const wxPoint& position)
{
	// Send the information to the other side
	this->sendDataToRemoteSide(NetworkEventData::MOUSE_UP, position);
	// Let the draw controller handle the event
	mDynamicDrawController->handleMouseUp(position);
	// The user's turn is over, lets change to the next turn
	mGameStartedController->changeSubState(this->getNextSubStateController());
}

bool LocalTurnSubStateController::handleMouseMotion(const wxPoint& position)
{
	int frequency = wxGetApp().getConfiguration()->getNetworkConfiguration()->getFrequency();
	bool isDataSendingNeeded = false;

	isDataSendingNeeded = mDynamicDrawController->handleMouseMotion(position);
	mMouseMotionCounter++;
	// Send the information to the other side if needed
	if(true == isDataSendingNeeded && frequency > 0 && (mMouseMotionCounter % frequency) == 0)
		this->sendDataToRemoteSide(NetworkEventData::MOUSE_MOTION, position);
	return isDataSendingNeeded;
}

const wxBitmap& LocalTurnSubStateController::getBitmapToPaint() const
{
	return mDynamicDrawController->getBitmapToPaint();
}

wxBitmap& LocalTurnSubStateController::getBitmapToDraw()
{
	return mDynamicDrawController->getBitmapToDraw();
}

//
// Methods inherited from GameStateController
//

void LocalTurnSubStateController::handleSocketConnection(wxSocketEvent&)
{
	wxASSERT_MSG(false, wxT("LocalTurnSubStateController::handleSocketConnection called. Could not happen!"));
}

void LocalTurnSubStateController::handleSocketLost(wxSocketEvent&)
{
	wxASSERT_MSG(false, wxT("LocalTurnSubStateController::handleSocketLost called. Could not happen!"));
}

void LocalTurnSubStateController::handleSocketInput(wxSocketEvent& socketEvent)
{
	wxASSERT_MSG(false, wxT("LocalTurnSubStateController::handleSocketInput called. Could not happen!"));
}

void LocalTurnSubStateController::handleSocketOutput(wxSocketEvent&)
{
	wxASSERT_MSG(false, wxT("LocalTurnSubStateController::handleSocketOutput called. Could not happen!"));
}

//
// Methods inherited from GameStartedSubStateController
//

GameStartedSubStateController::SubstateId LocalTurnSubStateController::getSubstateId()
{
	return GameStartedSubStateController::LOCAL_TURN;
}

GameStartedSubStateController* LocalTurnSubStateController::getNextSubStateController()
{
	// Create a new draw controller from the current one
	SmartPointer<DynamicDrawController> dynamicDrawController = new DynamicDrawController(mLevel, mOriginalLevel,
																						  mDynamicDrawController->getRemoteVehicle(),
																						  mDynamicDrawController->getActualVehicle(),
																						  mDynamicDrawController->getRemoteVehicleArrows(),
																						  mDynamicDrawController->getActualVehicleArrows(),
																						  mDynamicDrawController->getFirstStep());
	return new RemoteTurnSubStateController(mLevel, mOriginalLevel, dynamicDrawController);
}
